﻿// -------------------------------------------------------------------------
//    @FileName         :    NFWorldWelfareMgr.cpp
//    @Author           :    gaoyi
//    @Date             :    2025-06-30
//    @Email			:    445267987@qq.com
//    @Module           :    NFWorldWelfareMgr
//
// -------------------------------------------------------------------------

#include "NFWorldWelfareMgr.h"

#include "NFWorldWelfareDBData.h"
#include "NFWorldWelfareService.h"
#include "proto_svr_common.nanopb.h"
#include "WelfareDescEx.h"
#include "DescStore/WelfareDeleteDesc.h"

#include "NFServerComm/NFServerCommon/NFIServerMessageModule.h"
#include "proto_svr_world.pb.h"
#include "NFComm/NFCore/NFServerTime.h"
#include "NFComm/NFPluginModule/NFRoute.h"

NFWorldWelfareMgr::NFWorldWelfareMgr()
{
    if (EN_OBJ_MODE_INIT == NFShmMgr::Instance()->GetCreateMode())
    {
        CreateInit();
    }
    else
    {
        ResumeInit();
    }
}

NFWorldWelfareMgr::~NFWorldWelfareMgr()
{
}

int NFWorldWelfareMgr::CreateInit()
{
    m_dwLastTickUnixSec = 0;
    m_dwConfLastChangeUnixSec = 0;
    m_dwGameOpenUnixSec = 0;
    m_iOldConfigNum = 0;
    //1s执行一次
    SetTimer(1000, 0, 0, 0, 0, 0);
    return 0;
}

int NFWorldWelfareMgr::ResumeInit()
{
    return 0;
}

int NFWorldWelfareMgr::Awake()
{
    RegisterServerMessageWithModule(NF_ST_WORLD_SERVER, SS_MSGID_WORLD, proto_ff::SS_SUB_MSGID_WORLD_SYNC_WELFARE_DATA);
    return 0;
}

int NFWorldWelfareMgr::OnHandleServerMessage(uint64_t unLinkId, NFDataPackage& packet)
{
    if (!NFGlobalSystem::Instance()->GetGlobalPluginManager()->IsInited(NF_ST_WORLD_SERVER))
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "World Server not inited, drop client msg:{}", packet.ToString());
        return -1;
    }

    if (NFGlobalSystem::Instance()->GetGlobalPluginManager()->IsServerStopping())
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "World Server is Stopping, drop client msg:{}", packet.ToString());
        return -1;
    }

    if (packet.mModuleId == SS_MSGID_WORLD)
    {
        switch (packet.nMsgId)
        {
            case proto_ff::SS_SUB_MSGID_WORLD_SYNC_WELFARE_DATA:
            {
                OnHandleSyncWelfareData(unLinkId, packet);
                break;
            }
            default:
            {
                NFLogError(NF_LOG_DEFAULT, packet.nParam1, "World Server Get UnHandle Msg:{}", packet.ToString());
                break;
            }
        }
    }

    return 0;
}

int NFWorldWelfareMgr::OnHandleSyncWelfareData(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::SSWorldWelfareSyncAllData rsp;
    int iRet = CheckConfHadLoad();
    rsp.set_result(iRet);
    if (iRet == 0)
    {
        NFWorldWelfareDBData::Instance()->GetWorldDBData(*rsp.mutable_m_stdbdatares());
        GetAllConf(*rsp.mutable_m_stconfres());
        GetShowAndOpen(*rsp.mutable_m_stopenshowres());
    }
    FindModule<NFIMessageModule>()->SendTrans(NF_ST_WORLD_SERVER, NF_ST_LOGIC_SERVER, 0, packet.nSrcId, SS_MSGID_WORLD, proto_ff::SS_SUB_MSGID_WORLD_SYNC_WELFARE_DATA, rsp, 0, 0, packet.nParam1);
    return 0;
}

int NFWorldWelfareMgr::CheckConfHadLoad() const
{
    if (m_dwConfLastChangeUnixSec == 0)
    {
        CHECK_WARN(0, -1, "not load any conf");
    }

    if (m_stConf.GetConf().size() <= 0)
    {
        CHECK_WARN(0, -1, "not load any conf,");
    }
    return 0;
}

int NFWorldWelfareMgr::OnTimer(int timeId, int callCount)
{
    Tick();
    return 0;
}

int NFWorldWelfareMgr::Tick()
{
    if (!NFGlobalSystem::Instance()->GetGlobalPluginManager()->IsInited(NF_ST_WORLD_SERVER))
    {
        return 0;
    }

    if (NFGlobalSystem::Instance()->GetGlobalPluginManager()->IsServerStopping())
    {
        return 0;
    }

    uint32_t dwUnixSec = NF_ADJUST_TIMENOW();
    uint32_t dwLastTickUnixSecPre = m_dwLastTickUnixSec; // 上次tick时刻
    m_dwLastTickUnixSec = dwUnixSec;

    int iRetCode = 0;
    bool bConfChange = false;
    iRetCode = ProcConfChange(bConfChange);
    CHECK_ERR(0, iRetCode, "ProcConfChange failed");

    iRetCode = ProcOpenClose(dwUnixSec, dwLastTickUnixSecPre, bConfChange);
    CHECK_ERR(0, iRetCode, "ProcOpenClose failed");
    return 0;
}

int NFWorldWelfareMgr::ProcOpenClose(uint32_t dwUnixSec, uint32_t dwLastTickUnixSecPre, bool bConfChange)
{
    int iRetCode = 0;
    // 多少秒检测一次
    uint32_t checkSec = 60;
    if (!bConfChange) // 配置未变动
    {
        // 和上次检测在同一时间段，间隔未到,不需要检测
        if ((dwLastTickUnixSecPre / checkSec) == (dwUnixSec / checkSec))
        {
            return 0;
        }
    }

    auto& stCWelfareConf = GetConf();
    if (m_iOldConfigNum != (int)stCWelfareConf.GetConf().size())
    {
        for (auto iter = m_stWorldOpenShowData.m_aullShowWelfareID.begin(); iter != m_stWorldOpenShowData.m_aullShowWelfareID.end();)
        {
            auto pConf = stCWelfareConf.FindConf(*iter);
            if (pConf == nullptr)
            {
                iter = m_stWorldOpenShowData.m_aullShowWelfareID.erase(iter);
            }
            else
            {
                ++iter;
            }
        }
        for (auto iter = m_stWorldOpenShowData.m_aullOpenWelfareID.begin(); iter != m_stWorldOpenShowData.m_aullOpenWelfareID.end();)
        {
            auto pConf = stCWelfareConf.FindConf(*iter);
            if (pConf == nullptr)
            {
                iter = m_stWorldOpenShowData.m_aullOpenWelfareID.erase(iter);
            }
            else
            {
                ++iter;
            }
        }
        m_iOldConfigNum = stCWelfareConf.GetConf().size();
    }

    for (auto iter = stCWelfareConf.GetConf().list_begin(); iter != stCWelfareConf.GetConf().list_end(); ++iter)
    {
        auto* pWelfareOneConf = &iter->second;
        auto& stWelfareDesc = pWelfareOneConf->GetWelfareConf();
        CheckForClose(&stWelfareDesc, dwUnixSec);
        CheckForHide(&stWelfareDesc, dwUnixSec);
        CheckForShow(&stWelfareDesc, dwUnixSec);
        CheckForOpen(&stWelfareDesc, dwUnixSec);
    }

    int iSyncType = bConfChange ? 1 : 0;
    iRetCode = SyncShowAndOpenToGameSvr(0, iSyncType);
    CHECK_ERR(0, iRetCode, "SyncAllConfToGameSvr iSyncType:{}", iSyncType);
    return 0;
}

int NFWorldWelfareMgr::CheckForShow(const E_Welfare* pDesc, uint32_t dwUnixSec)
{
    CHECK_NULL(0, pDesc);
    if (IsShowWelfareId(pDesc->m_welfareId))
    {
        return 0;
    }

    int iRetCode = 0;
    bool bOpenAndInTimeRange = false;
    iRetCode = CheckIsOpenAndInTimeRange(pDesc, pDesc->m_showUnixTimeRange, dwUnixSec, bOpenAndInTimeRange);
    CHECK_ERR(0, iRetCode, "CheckIsOpenAndInTimeRange welfareID:{} dwUnixSec:{}", pDesc->m_welfareId, dwUnixSec);
    if (!bOpenAndInTimeRange)
    {
        return 0;
    }

    iRetCode = AddShowWelfareId(pDesc->m_welfareId);
    CHECK_ERR(0, iRetCode, "AddShowWelfareId welfareID:{}", pDesc->m_welfareId);

    LOG_INFO(0, "Show New welfareID:{}", pDesc->m_welfareId);
    return 0;
}

int NFWorldWelfareMgr::CheckForHide(const E_Welfare* pDesc, uint32_t dwUnixSec)
{
    CHECK_NULL(0, pDesc);
    CHECK_NULL(0, pDesc);
    if (!IsShowWelfareId(pDesc->m_welfareId))
    {
        return 0;
    }

    int iRetCode = 0;
    bool bOpenAndInTimeRange = false;
    iRetCode = CheckIsOpenAndInTimeRange(pDesc, pDesc->m_showUnixTimeRange, dwUnixSec, bOpenAndInTimeRange);
    CHECK_ERR(0, iRetCode, "CheckIsOpenAndInTimeRange welfareID:{} dwUnixSec:{}", pDesc->m_welfareId, dwUnixSec);
    if (bOpenAndInTimeRange)
    {
        return 0;
    }

    EraseShowWelfareId(pDesc->m_welfareId);

    LOG_INFO(0, "Hide Old welfareID:{}", pDesc->m_welfareId);
    return 0;
}

int NFWorldWelfareMgr::CheckForClose(const E_Welfare* pDesc, uint32_t dwUnixSec)
{
    CHECK_NULL(0, pDesc);

    if (!IsOpenWelfareId(pDesc->m_welfareId))
    {
        return 0;
    }

    int iRetCode = 0;
    bool bOpenAndInTimeRange = false;
    iRetCode = CheckIsOpenAndInTimeRange(pDesc, pDesc->m_openUnixTimeRange, dwUnixSec, bOpenAndInTimeRange);
    CHECK_ERR(0, iRetCode, "CheckIsOpenAndInTimeRange welfareID:{} dwUnixSec:{}", pDesc->m_welfareId, dwUnixSec);
    if (bOpenAndInTimeRange)
    {
        return 0;
    }

    EraseOpenWelfareId(pDesc->m_welfareId);
    LOG_INFO(0, "Close Old welfareID:{}", pDesc->m_welfareId);
    return 0;
}

int NFWorldWelfareMgr::CheckForOpen(const E_Welfare* pDesc, uint32_t dwUnixSec)
{
    CHECK_NULL(0, pDesc);
    if (pDesc->m_close != 0)
    {
        return 0;
    }

    if (!IsShowWelfareId(pDesc->m_welfareId))
    {
        return 0;
    }

    if (IsOpenWelfareId(pDesc->m_welfareId))
    {
        return 0;
    }

    int iRetCode = 0;
    bool bOpenAndInTimeRange = false;
    iRetCode = CheckIsOpenAndInTimeRange(pDesc, pDesc->m_openUnixTimeRange, dwUnixSec, bOpenAndInTimeRange);
    CHECK_ERR(0, iRetCode, "CheckIsOpenAndInTimeRange welfareID:{} dwUnixSec:{}", pDesc->m_welfareId, dwUnixSec);
    if (!bOpenAndInTimeRange)
    {
        return 0;
    }

    iRetCode = AddOpenWelfareId(pDesc->m_welfareId);
    CHECK_ERR(0, iRetCode, "AddOpenWelfareId failed, welfareID:{}", pDesc->m_welfareId);
    LOG_INFO(0, "Open New welfareID:{}", pDesc->m_welfareId);
    return 0;
}

int NFWorldWelfareMgr::CheckIsOpenAndInTimeRange(const E_Welfare* pDesc, const UnixTimeRange& timeRange, uint32_t dwUnixSec, bool& bOpenAndInTimeRange) const
{
    int iRetCode = 0;
    CHECK_NULL(0, pDesc);
    if (pDesc->m_close != 0)
    {
        return 0;
    }

    iRetCode = NFWorldWelfareService::CheckInUnixTimeRange(timeRange, dwUnixSec);
    if (iRetCode != 0)
    {
        return 0;
    }

    iRetCode = CheckIsShowBySvrOpenTime(pDesc);
    if (iRetCode != 0)
    {
        return 0;
    }

    if (pDesc->m_openWeekDay != 0)
    {
        int iWeekDay = NFTimeUtility::GetWeekDay127(dwUnixSec);
        int iDayFlag = pDesc->m_openWeekDay & (1 << (iWeekDay - 1));
        if (iDayFlag == 0)
        {
            return 0;
        }
    }

    bOpenAndInTimeRange = true;

    return 0;
}

int NFWorldWelfareMgr::CheckIsShowBySvrOpenTime(const E_Welfare* pDesc) const
{
    int iRetCode = 0;
    CHECK_NULL(0, pDesc);
    if (pDesc->m_close != 0)
    {
        return 0;
    }

    uint32_t dwServerOpenTime = 0;
    iRetCode = NFWorldWelfareService::GetServerOpenTime(dwServerOpenTime);
    CHECK_ERR(0, iRetCode, "GetServerOpenTime failed");
    if (dwServerOpenTime > pDesc->m_stSvrOpenTimeBefore.m_szTime_t)
    {
        return 1;
    }

    if (dwServerOpenTime < pDesc->m_stSvrOpenTimeAfter.m_szTime_t)
    {
        return 2;
    }

    return 0;
}

int NFWorldWelfareMgr::LoadWelfareXls(NFWelfareConf& stConf, uint32_t dwGameOpenDayBeginUnixSec)
{
    int iRetCode = 0;
    for (int i = 0; i < WelfareDesc::Instance()->GetResNum(); i++)
    {
        auto pDesc = WelfareDesc::Instance()->GetDescByIndex(i);
        CHECK_NULL(0, pDesc);

        auto pConfOne = stConf.AllocConf(pDesc->m_welfareId);
        CHECK_NULL_WF(0, pConfOne, "AllocConf failed, welfareId:{}", pDesc->m_welfareId);

        iRetCode = pConfOne->SetConfData(pDesc->m_welfareId, m_dwConfLastChangeUnixSec, dwGameOpenDayBeginUnixSec, NFGlobalSystem::Instance()->GetGlobalPluginManager()->GetZoneID());
        CHECK_ERR(0, iRetCode, "pConfOne->SetConfData failed, welfareId:{}", pDesc->m_welfareId);
    }

    return 0;
}

int NFWorldWelfareMgr::ProcConfChange(bool& bConfChange)
{
    int iRetCode = 0;
    uint32_t dwLastChangeUnixSec = WelfareDescEx::Instance()->GetLastChangeUnixSec();
    uint32_t dwConfLastChangeUnixSecPre = m_dwConfLastChangeUnixSec;
    if (dwLastChangeUnixSec == dwConfLastChangeUnixSecPre)
    {
        return 0;
    }

    uint32_t dwGameOpenUnixSec = 0;
    iRetCode = NFWorldWelfareService::GetServerOpenTime(dwGameOpenUnixSec);
    CHECK_ERR(0, iRetCode, "NFWorldWelfareService::GetGameOpenUnixSec faield");

    uint32_t dwGameOpenDayBeginUnixSec = NFTimeUtility::GetTodayStartTime(dwGameOpenUnixSec);
    LOG_INFO(0, "dwLastChangeUnixSec:{} m_dwConfLastChangeUnixSec:{} dwGameOpenUnixSec:{} dwGameOpenDayBeginUnixSec:{}",
             NFTimeUtility::DateTimeToStr(dwLastChangeUnixSec), NFTimeUtility::DateTimeToStr(m_dwConfLastChangeUnixSec), NFTimeUtility::DateTimeToStr(dwGameOpenUnixSec), NFTimeUtility::DateTimeToStr(dwGameOpenDayBeginUnixSec));

    int iOldConfigNum = m_stConf.GetConf().size();

    static NFWelfareConf stConfTemp;
    iRetCode = stConfTemp.Reset();
    CHECK_ERR(0, iRetCode, "stConfTemp.Reset failed");

    iRetCode = LoadWelfareXls(stConfTemp, dwGameOpenDayBeginUnixSec);
    CHECK_ERR(0, iRetCode, "LoadWelfareXls Failed");

    WelfareDBWorldDataConfig* pConfig = NFWorldWelfareDBData::Instance()->GetConfig();
    CHECK_NULL(0, pConfig);

    WelfareDBWorldDataConfig stTmpWelfareDBWorldDataConfig = *pConfig;
    bool bChange = false;

    iRetCode = CheckAndSetDBConfig(stConfTemp, stTmpWelfareDBWorldDataConfig, bChange);
    CHECK_ERR(0, iRetCode, "CheckAndSetDBConfig failed");

    int iSyncType = 2; //2 reload
    if (dwConfLastChangeUnixSecPre == 0)
    {
        iSyncType = 0;
    }
    LOG_INFO(0, "bChange:{} iSyncType:{}", bChange, iSyncType);

    static NFWelfareConf stConfBak;
    stConfBak.Reset();
    stConfBak = m_stConf;
    uint32_t dwConfLastChangeUnixSecBak = m_dwConfLastChangeUnixSec;

    m_stConf = stConfTemp;
    m_dwConfLastChangeUnixSec = dwLastChangeUnixSec;
    iRetCode = SyncAllConfToGameSvr(0, iSyncType);
    if (iRetCode != 0)
    {
        m_stConf = stConfBak;
        m_dwConfLastChangeUnixSec = dwConfLastChangeUnixSecBak;
        CHECK_ERR(0, iRetCode, "SyncAllConfToGamesvr iSyncType:{}", iSyncType);
    }

    m_dwGameOpenUnixSec = dwGameOpenUnixSec;
    bConfChange = true;
    m_dwConfLastChangeUnixSec = dwLastChangeUnixSec;
    m_iOldConfigNum = iOldConfigNum;
    if (bChange)
    {
        *pConfig = stTmpWelfareDBWorldDataConfig;
        NFWorldWelfareDBData::Instance()->MarkDirty();
    }

    return 0;
}

int NFWorldWelfareMgr::CheckAndSetDBConfig(const NFWelfareConf& stConf, WelfareDBWorldDataConfig& stWelfareDBWorldDataConfig, bool& bChange)
{
    int iRetCode = 0;
    iRetCode = CheckAndSetDBDeleteWelfareConfig(stWelfareDBWorldDataConfig, bChange);
    CHECK_ERR(0, iRetCode, "CheckAndSetDBDeleeteWelfareConfig failed");

    for (auto iter = stWelfareDBWorldDataConfig.m_astConfig.begin(); iter != stWelfareDBWorldDataConfig.m_astConfig.end();)
    {
        WelfareDBWorldDataConfigWelfare& stDBConfig = iter->second;
        LOG_INFO(0, "welfare:{} in db", stDBConfig.m_ullWelfareID);

        if (stDBConfig.m_enType == WELFARE_TYPE_CONFIG)
        {
            continue;
        }

        auto* pCWelfareConfOne = stConf.FindConf(stDBConfig.m_ullWelfareID);
        if (pCWelfareConfOne == nullptr)
        {
            if (CanDeleteWelfareDesc(stDBConfig))
            {
                iter = stWelfareDBWorldDataConfig.m_astConfig.erase(iter);
                bChange = true;
                continue;
            }

            CHECK_NULL_WF(0, pCWelfareConfOne, "del welfare, welfareId:{}", stDBConfig.m_ullWelfareID);
        }

        if (pCWelfareConfOne->GetWelfareConf().m_notRecordToDB)
        {
            LOG_INFO(0, "welfare:{} not record to db", stDBConfig.m_ullWelfareID);
            ++iter;
            continue;
        }

        bool bWelfareChange = false;
        iRetCode = CheckAndUpdDBConfigWelfare(stDBConfig, *pCWelfareConfOne, bWelfareChange);
        CHECK_ERR(0, iRetCode, "CheckAndUpdDBConfigWelfare failed, stDBConfig:{} stWelfareDesc:{}", stDBConfig.ShortDebugString(), pCWelfareConfOne->GetWelfareConf().ShortDebugString());

        bChange = bChange || bWelfareChange;
        ++iter;
    }

    for (auto iter = stConf.GetConf().list_begin(); iter != stConf.GetConf().list_end(); ++iter)
    {
        auto pWelfareConfOne = &iter->second;
        CHECK_NULL(0, pWelfareConfOne);
        if (stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.find(pWelfareConfOne->GetWelfareID()) != stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.end())
        {
            CHECK_ERR(0, -1, "welfareId:{} in db delete list, must not in xlsx", pWelfareConfOne->GetWelfareID());
        }

        if (stWelfareDBWorldDataConfig.m_astConfig.find(pWelfareConfOne->GetWelfareID()) != stWelfareDBWorldDataConfig.m_astConfig.end())
        {
            continue;
        }

        auto& stWelfareDesc = pWelfareConfOne->GetWelfareConf();
        if (stWelfareDesc.m_notRecordToDB)
        {
            LOG_INFO(0, "welfareId:{} not record to db, skip", pWelfareConfOne->GetWelfareID());
            continue;
        }

        if (stWelfareDesc.m_type == WELFARE_TYPE_CONFIG)
        {
            LOG_INFO(0, "welfareId:{} type:{} not record to db, skip", pWelfareConfOne->GetWelfareID(), pWelfareConfOne->GetWelfareConf().m_type);
            continue;
        }

        LOG_INFO(0, "add welfareId:{} type:{} record to db", pWelfareConfOne->GetWelfareID(), pWelfareConfOne->GetWelfareConf().m_type);
        if (stWelfareDBWorldDataConfig.m_astConfig.full())
        {
            CHECK_ERR(0, -1, "db config full");
        }

        WelfareDBWorldDataConfigWelfare newDBConfig;
        iRetCode = FillDBConfigWelfare(*pWelfareConfOne, newDBConfig);
        CHECK_ERR(0, iRetCode, "FillDBConfigWelfare failed, welfareId:{}", pWelfareConfOne->GetWelfareID());

        stWelfareDBWorldDataConfig.m_astConfig[newDBConfig.m_ullWelfareID] = newDBConfig;
        bChange = true;
    }
    return 0;
}

int NFWorldWelfareMgr::CheckAndUpdDBConfigWelfare(WelfareDBWorldDataConfigWelfare& stDBConfig, const NFWelfareConfOne& stWelfareConfOne, bool& bChange)
{
    int iRetCode = 0;

    auto& stWelfareDesc = stWelfareConfOne.GetWelfareConf();
    if (stWelfareDesc.m_type != stDBConfig.m_enType)
    {
        CHECK_ERR(0, -1, "welfareId:{} config type:{} != db type:{}", stDBConfig.m_ullWelfareID, stWelfareDesc.m_type, stDBConfig.m_enType);
    }

    if ((int)stDBConfig.m_astNode.size() > stWelfareConfOne.GetNodeNum())
    {
        CHECK_ERR(0, -1, "welfareId:{} node change, db node num:{} > config node num:{}", stDBConfig.m_ullWelfareID, stDBConfig.m_astNode.size(), stWelfareConfOne.GetNodeNum());
    }
    else if ((int)stDBConfig.m_astNode.size() == stWelfareConfOne.GetNodeNum())
    {
        for (auto db_iter = stDBConfig.m_astNode.list_begin(); db_iter != stDBConfig.m_astNode.list_end(); ++db_iter)
        {
            auto& stDBNodeConfig = db_iter->second;
            auto pWelfareNodeDesc = stWelfareConfOne.FindNodeByNodeID(stDBNodeConfig.m_iNodeId);
            CHECK_NULL_WF(0, pWelfareNodeDesc, "welfareId:{} node change, db node id:{} != config node id", stDBConfig.m_ullWelfareID, db_iter->second.m_iNodeId);

            bool bNodeChange = false;
            iRetCode = CheckAndUpdDBConfigWelfareNode(stDBNodeConfig, *pWelfareNodeDesc, bNodeChange);
            CHECK_ERR(0, iRetCode, "CheckAndUpdDBConfigWelfareNode failed, stDBNodeConfig:{} pWelfareNodeDesc:{}", stDBNodeConfig.ShortDebugString(), pWelfareNodeDesc->ShortDebugString());
            bChange = bChange || bNodeChange;
        }
    }
    else
    {
        LOG_INFO(0, "welfareId:{} node change, db node num:{} < config node num:{}", stDBConfig.m_ullWelfareID, stDBConfig.m_astNode.size(), stWelfareConfOne.GetNodeNum());

        WelfareDBWorldDataConfigWelfare stDBConfigNew;
        iRetCode = FillDBConfigWelfare(stWelfareConfOne, stDBConfigNew);
        CHECK_ERR(0, iRetCode, "FillDBConfigWelfare failed");

        stDBConfig = stDBConfigNew;
        bChange = true;
    }

    return 0;
}

int NFWorldWelfareMgr::FillDBConfigWelfare(const NFWelfareConfOne stWelfareConfOne, WelfareDBWorldDataConfigWelfare& stDBConfig)
{
    stDBConfig.Init();
    auto& stWelfareDesc = stWelfareConfOne.GetWelfareConf();
    stDBConfig.m_ullWelfareID = stWelfareDesc.m_welfareId;
    stDBConfig.m_enType = stWelfareDesc.m_type;

    if (stWelfareConfOne.GetNodeNum() > stDBConfig.m_astNode.max_size())
    {
        CHECK_ERR(0, -1, "welfareId:{} config node num > db max num:{}", stWelfareDesc.m_welfareId, stWelfareConfOne.GetNodeNum(), stDBConfig.m_astNode.max_size());
    }

    for (auto iter = stWelfareConfOne.GetConf().m_astWelfareNodeDesc.list_begin(); iter != stWelfareConfOne.GetConf().m_astWelfareNodeDesc.list_end(); ++iter)
    {
        auto* pWelfareNodeDesc = &iter->second;
        CHECK_NULL(0, pWelfareNodeDesc);

        auto& stNode = stDBConfig.m_astNode[pWelfareNodeDesc->m_nodeId];
        stNode.Init();

        stNode.m_iNodeId = pWelfareNodeDesc->m_nodeId;
        stNode.m_enType = pWelfareNodeDesc->m_type;
        stNode.m_dwShowOrder = pWelfareNodeDesc->m_dwShowOrder;
        stNode.m_bShowOrderInit = true;
    }

    LOG_DEBUG(0, "welfareId:{} FillDBConfigWelfare, stDBConfig:{}", stWelfareDesc.m_welfareId, stDBConfig.ShortDebugString());
    return 0;
}

int NFWorldWelfareMgr::CheckAndUpdDBConfigWelfareNode(WelfareDBWorldDataConfigWelfareNode& stDBConfig, const E_WelfareNode& stConf, bool& bChange)
{
    if (stDBConfig.m_enType != stConf.m_type)
    {
        CHECK_ERR(0, -1, "welfareId:{} node change, db node type:{} != config node type:{}", stConf.m_welfareId, stDBConfig.m_enType, stConf.m_type);
    }

    bChange = false;
    WelfareDBWorldDataConfigWelfareNode stPreDB = stDBConfig;

    if (!stDBConfig.m_bShowOrderInit)
    {
        stDBConfig.m_dwShowOrder = stConf.m_dwShowOrder;
        stDBConfig.m_bShowOrderInit = true;
        bChange = true;
    }
    else
    {
        // m_dwShowOrder不允许从0变更为非0
        if (0 == stDBConfig.m_dwShowOrder && 0 != stConf.m_dwShowOrder)
        {
            CHECK_ERR(0, -1, "cant chg from 0 to !0. in db m_dwShowOrder:{} but now m_dwShowOrder:{}",
                      stDBConfig.m_dwShowOrder, stConf.m_dwShowOrder);
        }

        if ((int)stDBConfig.m_dwShowOrder != stConf.m_dwShowOrder)
        {
            stDBConfig.m_dwShowOrder = stConf.m_dwShowOrder;
            bChange = true;
        }
    }

    if (bChange)
    {
        LOG_INFO(0, "WelfareID:{} NodeID:{} PreDB:{} CurDB:{}", stConf.m_welfareId, stConf.m_nodeId,
                 stPreDB.ShortDebugString(), stDBConfig.ShortDebugString());
    }
    return 0;
}

bool NFWorldWelfareMgr::CanDeleteWelfareDesc(const WelfareDBWorldDataConfigWelfare& stDBConfig)
{
    auto pDesc = WelfareDeleteDesc::Instance()->GetDesc(stDBConfig.m_ullWelfareID);
    if (pDesc)
    {
        return true;
    }

    return false;
}

int NFWorldWelfareMgr::CheckAndSetDBDeleteWelfareConfig(WelfareDBWorldDataConfig& stWelfareDBWorldDataConfig, bool& bChange)
{
    if ((int)stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.size() > WelfareDeleteDesc::Instance()->GetResNum())
    {
        CHECK_ERR(0, -1, "stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.size() > WelfareDeleteDesc::Instance()->GetResNum()", stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.size(), WelfareDeleteDesc::Instance()->GetResNum());
    }

    std::unordered_set<uint64_t> setInDBDeleteWelfareID;
    for (auto iter = WelfareDeleteDesc::Instance()->GetResDesc().begin(); iter != WelfareDeleteDesc::Instance()->GetResDesc().end(); ++iter)
    {
        setInDBDeleteWelfareID.insert(iter->m_id);
    }

    for (auto iter = stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.begin(); iter != stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.end(); ++iter)
    {
        uint64_t ullWelfareID = *iter;
        if (setInDBDeleteWelfareID.find(ullWelfareID) == setInDBDeleteWelfareID.end())
        {
            CHECK_ERR(0, -1, "WelfareID:{} in db, but not in the delete excel", ullWelfareID);
        }
        setInDBDeleteWelfareID.erase(ullWelfareID);
    }

    if (setInDBDeleteWelfareID.size() == 0)
    {
        LOG_INFO(0, "No new deleted welfare count:{}", stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.size());
        return 0;
    }

    LOG_INFO(0, "Will Add new deleted welfare count:{} curr:{}", setInDBDeleteWelfareID.size(), stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.size());
    for (uint64_t ullNewDelWelfareID : setInDBDeleteWelfareID)
    {
        if (stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.full())
        {
            CHECK_ERR(0, -1, "db delete welfare list full");
        }

        stWelfareDBWorldDataConfig.m_aullDeletedWelfareID.insert(ullNewDelWelfareID);
        LOG_INFO(0, "Add new deleted welfare:{}", ullNewDelWelfareID);
        bChange = true;
    }

    return 0;
}

int NFWorldWelfareMgr::GetAllConf(proto_ff::SSWorldWelfareSyncConfRes& res) const
{
    res.set_m_isynctype(0);
    res.set_m_dwconfloadunixsec(m_dwConfLastChangeUnixSec);
    for (auto iter = m_stConf.GetConf().list_begin(); iter != m_stConf.GetConf().list_end(); ++iter)
    {
        iter->second.GetConf().ToPb(res.add_m_astconf());
    }
    return 0;
}

int NFWorldWelfareMgr::GetShowAndOpen(proto_ff::SSWorldWelfareSyncOpenShowRes& res) const
{
    res.set_m_isynctype(0);
    m_stWorldOpenShowData.ToPb(res.mutable_m_stopenshowdata());
    return 0;
}

int NFWorldWelfareMgr::SyncAllConfToGameSvr(int iSvrID, int iSyncType) const
{
    proto_ff::SSWorldWelfareSyncConfRes res;
    GetAllConf(res);
    res.set_m_isynctype(iSyncType);

    if (iSvrID == 0)
    {
        FindModule<NFIServerMessageModule>()->SendMsgToLogicServer(NF_ST_WORLD_SERVER, LOCAL_ALL_ROUTE, SS_MSGID_WORLD, SS_SUB_MSGID_WORLD_WELFARE_SYNC_CONF, res);
    }
    else
    {
        FindModule<NFIServerMessageModule>()->SendMsgToLogicServer(NF_ST_WORLD_SERVER, iSvrID, SS_MSGID_WORLD, SS_SUB_MSGID_WORLD_WELFARE_SYNC_CONF, res);
    }
    return 0;
}

int NFWorldWelfareMgr::SyncShowAndOpenToGameSvr(int iSvrID, int iSyncType) const
{
    proto_ff::SSWorldWelfareSyncOpenShowRes res;
    GetShowAndOpen(res);
    res.set_m_isynctype(iSyncType);

    if (iSvrID == 0)
    {
        FindModule<NFIServerMessageModule>()->SendMsgToLogicServer(NF_ST_WORLD_SERVER, LOCAL_ALL_ROUTE, SS_MSGID_WORLD, SS_SUB_MSGID_WORLD_WELFARE_SYNC_OPENSHOW, res);
    }
    else
    {
        FindModule<NFIServerMessageModule>()->SendMsgToLogicServer(NF_ST_WORLD_SERVER, iSvrID, SS_MSGID_WORLD, SS_SUB_MSGID_WORLD_WELFARE_SYNC_OPENSHOW, res);
    }
    return 0;
}

bool NFWorldWelfareMgr::IsOpenWelfareId(uint64_t welfareId)
{
    auto iter = m_stWorldOpenShowData.m_aullOpenWelfareID.find(welfareId);
    if (iter != m_stWorldOpenShowData.m_aullOpenWelfareID.end())
    {
        return true;
    }
    return false;
}

void NFWorldWelfareMgr::EraseOpenWelfareId(uint64_t welfareId)
{
    m_stWorldOpenShowData.m_aullOpenWelfareID.erase(welfareId);
}

bool NFWorldWelfareMgr::IsShowWelfareId(uint64_t welfareId)
{
    auto iter = m_stWorldOpenShowData.m_aullShowWelfareID.find(welfareId);
    if (iter != m_stWorldOpenShowData.m_aullShowWelfareID.end())
    {
        return true;
    }
    return false;
}

void NFWorldWelfareMgr::EraseShowWelfareId(uint64_t welfareId)
{
    m_stWorldOpenShowData.m_aullShowWelfareID.erase(welfareId);
}

int NFWorldWelfareMgr::AddOpenWelfareId(uint64_t welfareId)
{
    if (m_stWorldOpenShowData.m_aullOpenWelfareID.full())
    {
        CHECK_ERR(0, -1, "m_stWorldOpenShowData.m_aullOpenWelfareID full, can't add welfareId:{}", welfareId);
    }

    m_stWorldOpenShowData.m_aullOpenWelfareID.insert(welfareId);
    return 0;
}

int NFWorldWelfareMgr::AddShowWelfareId(uint64_t welfareId)
{
    if (m_stWorldOpenShowData.m_aullShowWelfareID.full())
    {
        CHECK_ERR(0, -1, "m_stWorldOpenShowData.m_aullShowWelfareID full, can't add welfareId:{}", welfareId);
    }

    m_stWorldOpenShowData.m_aullShowWelfareID.insert(welfareId);
    return 0;
}

int NFWorldWelfareMgr::GetWorldDataOpenIDs(std::set<uint64_t>& stSetOpenId) const
{
    for (auto iter = m_stWorldOpenShowData.m_aullOpenWelfareID.begin(); iter != m_stWorldOpenShowData.m_aullOpenWelfareID.end(); ++iter)
    {
        auto pConfOne = m_stConf.FindConf(*iter);
        if (pConfOne == nullptr)
        {
            LOG_ERR(0, -1, "welfareId:{} conf not exist", *iter);
            continue;
        }

        if (NFWorldWelfareService::IsHaveWorldData(pConfOne->GetWelfareConf()))
        {
            stSetOpenId.insert(*iter);
        }
    }
    return 0;
}
